import React, {useState} from "react";
import {
  Card,
  CardHeader,
  Checkbox,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControlLabel,
  FormGroup,
  InputAdornment,
  ListItemIcon,
  OutlinedInput,
  Snackbar
} from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import SearchIcon from '@material-ui/icons/Search';
import IconButton from "@material-ui/core/IconButton";
import MoreVertIcon from '@material-ui/icons/MoreVert';
import {useSelector} from "react-redux";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import EqualizerIcon from "@material-ui/icons/Equalizer";
import Divider from "@material-ui/core/Divider";
import DeleteIcon from "@material-ui/icons/Delete";
import LinkIcon from '@material-ui/icons/Link';
import {indicatorResponseToQueryWrapper} from "../../../../ruleEngine/rulesGenerator";
import Backend from "../../../Backend/Backend";
import parse from "html-react-parser";
import PreviewIndicator from "./PreviewIndicator";
import CloseIcon from "@material-ui/icons/Close";

// const indicators = [
//   {id: 1, text: "Courses per semester", subText: "Basic Indicator"},
//   {id: 2, text: "Study program per degree", subText: "Basic Indicator"},
//   {
//     id: 3,
//     text: "Number of PDF file downloads per week",
//     subText: "Composite Indicator"
//   },
//   {
//     id: 4,
//     text: "Clusters of students failing/passing exam",
//     subText: "Basic Indicator"
//   },
//   {
//     id: 5,
//     text:
//       "Prediction of the number of students enrolling my course in the next semester",
//     subText: "Multi-level Indicator"
//   }
// ];

const borderRadius = "12px 4px 12px 4px";

export default function MyIndicators() {
  const userDefinedIndicators = useSelector(state => state.gqiEditor.common.userDefinedIndicators);
  const darkModeSelected = useSelector((state) => state.commonSettings.darkMode);
  const [hover, setHover] = useState(-1);
  const [visData, setVisData] = useState({});
  const [search, setSearch] = useState("");
  const [loading, setLoading] = React.useState(null);
  const [openDetails, setOpenDetails] = React.useState(false);
  const [indicators, setIndicators] = useState(userDefinedIndicators);
  const [filterIndicators, setFilterIndicators] = useState([
    "Basic Indicator",
    "Composite Indicator",
    "Multi-level Indicator"
  ]);

  const handleVisualization = async (indicator) => {
    setLoading(true);
    let vizQuery = indicatorResponseToQueryWrapper(indicator);

    // TODO: Update with async method
    await Backend.post("/AnalyticsEngine/GetIndicatorPreview", vizQuery)
      .then(response => {
        let unescapedVizCode = decodeURIComponent(response.data.visualizationCode);
        let objectData = parse(unescapedVizCode);
        let scriptData = objectData[1].props.dangerouslySetInnerHTML.__html;
        setVisData({name: indicator.name, objectData, scriptData});
        setLoading(false);
      }, (error) => {
        // TODO: Add a feedback
        console.log(error);
      })
  }

  // TODO: Search function buggy
  const searchIndicator = (e) => {
    setSearch(e.target.value);
    console.log(1)
    Backend.get("/")
    .then(response => {
      console.log('11')
    }, (error) => {
      // TODO: Add a feedback
      console.log(error);
    })
    let iArray = [];
    userDefinedIndicators.forEach(indicator => {
      console.log(indicator)
      if (indicator.name.match(e.target.value)) {
        iArray.push(indicator);
      }
    });
    setIndicators(iArray);
  };

  const filterIndicatorByIndicatorType = (e) => {
    let checked = e.target.checked;
    let id = e.target.id;
    let array = filterIndicators;
    if (!checked) {
      const index = array.indexOf(id);
      if (index > -1) {
        array.splice(index, 1);
      }
    } else {
      array.push(id);
    }
    setFilterIndicators(array);
    let iArray = [];
    userDefinedIndicators.forEach((indicator) => {
      if (filterIndicators.indexOf(indicator.indicatorType) !== -1) {
        iArray.push(indicator);
      }
    });
    setIndicators(iArray);
  };


  return (
    <>
      <Card style={{marginBottom: 32, borderRadius: borderRadius}}>
        <Grid container direction="column">
          <Grid item xs>
            <CardHeader
              action={<Button variant="contained" color="primary" style={{borderRadius: borderRadius}}>Create
                Indicator</Button>}
              title={<Typography>Create a new indicator</Typography>}/>
          </Grid>
        </Grid>
      </Card>

      <Grid container alignItems="center" style={{marginBottom: 24}} spacing={2}>
        <Grid item xs>
          <OutlinedInput size="small" id="outlined-adornment-weight" value={search} placeholder="Search for indicators"
                         onChange={searchIndicator} aria-describedby="outlined-weight-helper-text"
                         endAdornment={<InputAdornment position="end"> <SearchIcon color="disabled"/> </InputAdornment>}
                         inputProps={{"aria-label": "weight"}}
                         style={{
                           width: 300, borderRadius: borderRadius,
                           backgroundColor: !darkModeSelected ? '#fff' : ''
                         }}/>
        </Grid>
        <Grid item>
          <FormGroup>
            <Grid container alignItems="center">
              <Typography style={{marginRight: 8}}> Filter by indicator types: </Typography>
              <FormControlLabel label="Basic" control={<Checkbox id="Basic Indicator" defaultChecked color="primary"
                                                                 onChange={filterIndicatorByIndicatorType}/>}/>
              <FormControlLabel label="Composite"
                                control={<Checkbox id="Composite Indicator" defaultChecked color="primary"
                                                   onChange={filterIndicatorByIndicatorType}/>}/>
              <FormControlLabel label="Multi-level Indicator"
                                control={<Checkbox id="Multi-level Indicator" defaultChecked color="primary"
                                                   onChange={filterIndicatorByIndicatorType}/>}/>
            </Grid>
          </FormGroup>
        </Grid>
      </Grid>

      <Grid container justify="space-between" style={{marginBottom: 8}}>
        <Typography style={{fontWeight: "bold"}}> List of my indicators </Typography>
        <Typography> {indicators.length} indicators found </Typography>
      </Grid>

      {indicators.map((indicator, index) => {
        return (
          <>
            <Card key={index} style={{marginBottom: 8, borderRadius: borderRadius}} raised={index === hover}
                  onMouseEnter={() => setHover(index)} onMouseLeave={() => setHover(-1)}>
              <Grid container direction="column">
                <Grid item xs>
                  <CardHeader
                    action={<OptionsForIndicator indicator={indicator} handleVisualization={handleVisualization}
                                                 openDetails={openDetails} setOpenDetails={setOpenDetails}/>}
                    title={<Typography>{indicator.name}</Typography>}
                    subheader={indicator.indicatorType}
                  />
                </Grid>
              </Grid>
            </Card>
          </>
        );
      })}

      {/* Modal to preview the indicators specified for the question*/}
      <Dialog fullWidth maxWidth="sm" open={openDetails} onClose={() => setOpenDetails(!openDetails)}
              aria-labelledby="form-dialog-title">
        {!loading ? <>
          <DialogTitle id="form-dialog-title">{visData.name}</DialogTitle>
          <DialogContent>
            <Grid container justify="center" alignItems="center">
              <PreviewIndicator viz={visData}/>
            </Grid>
          </DialogContent>
        </> : <Grid container direction="column" alignItems="center" style={{marginTop: 32}}>
          <CircularProgress style={{marginBottom: 8}}/>
          <Typography>Loading indicator</Typography>
        </Grid>}
        <DialogActions>
          <Button onClick={() => setOpenDetails(!openDetails)}> Close </Button>
        </DialogActions>
      </Dialog>
    </>
  );
}

// A separate component for menu is required for correct item when onClick action is triggered.
// Read more: https://stackoverflow.com/questions/58041935/material-ui-menu-component-only-last-menuitem-onclick-action-is-triggered
const OptionsForIndicator = ({indicator, handleVisualization, openDetails, setOpenDetails}) => {
  const userQuestionsAndIndicators = useSelector(state => state.gqiEditor.common.userQuestionAndIndicators);
  const [openMenu, setOpenMenu] = React.useState(null);
  const [copiedCode, setCopiedCode] = useState(false);

  const copyIndicatorCode = (indicator) => {
    const {indicatorRequestCode} = indicator;
    navigator.clipboard.writeText(indicatorRequestCode).then(() => setCopiedCode(!copiedCode));
  }
  return (
    <>
      <IconButton onClick={(e) => setOpenMenu(e.currentTarget)}>
        <MoreVertIcon/>
      </IconButton>

      <Menu anchorEl={openMenu} keepMounted open={Boolean(openMenu)}
            onClose={() => setOpenMenu(null)} getContentAnchorEl={null}
            anchorOrigin={{vertical: 'bottom', horizontal: 'right'}}
            transformOrigin={{vertical: 'top', horizontal: 'right'}}>
        <MenuItem onClick={() => {
          handleVisualization(indicator)
          setOpenDetails(!openDetails);
          setOpenMenu(null);
        }}>
          <ListItemIcon> <EqualizerIcon/> </ListItemIcon>
          <Typography variant="inherit" noWrap> Show indicator </Typography>
        </MenuItem>

        <MenuItem style={{margin: "8px 0 8px 0"}} onClick={() => {
          // The indicator request code is only available inside the userQuestionAndIndicator variable
          // The indicator code is required to be extracted from there by identifying the id of the indicator
          userQuestionsAndIndicators.every(qi => qi.indicatorSaveResponses.every(i => {
            if (i.indicatorClientID === indicator.id) {
              copyIndicatorCode(i);
              return false;
            }
            return true;
          }))
          setOpenMenu(null);
        }}>
          <ListItemIcon> <LinkIcon/> </ListItemIcon>
          <Typography variant="inherit" noWrap> Embed code </Typography>
        </MenuItem>

        <Divider style={{margin: "8px 0 8px 0"}}/>

        <MenuItem onClick={() => setOpenMenu(null)}>
          <ListItemIcon> <DeleteIcon color="secondary"/> </ListItemIcon>
          <Typography variant="inherit" noWrap> Delete </Typography>
        </MenuItem>
      </Menu>

      {/* Feedback to copy code */}
      <Snackbar
        anchorOrigin={{vertical: "bottom", horizontal: "left"}}
        open={copiedCode}
        onClose={() => setCopiedCode(false)}
        autoHideDuration={3000}
        message="Code copied!"
        action={
          <IconButton size="small" aria-label="close" color="inherit" onClick={() => setCopiedCode(false)}>
            <CloseIcon fontSize="small"/>
          </IconButton>
        }
      />
    </>
  );
}
